/*
 * @Author: 0x9DEFA478
 * @Date: 2021-09-16 18:53:05
 * @LastEditTime: 2022-01-06 15:16:48
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "I_W25Q_DualBank.h"
#include "IP_GPIO.h"




//IO定义

//SCK

#define pI_W25Q_DualBank_SCK_GPIOx                                 GPIOB
#define vI_W25Q_DualBank_SCK_PinNum                                2


//Bank1

#define pI_W25Q_DualBank_BK1CS_GPIOx                               GPIOB
#define vI_W25Q_DualBank_BK1CS_PinNum                              6

#define pI_W25Q_DualBank_BK1IO0_GPIOx                              GPIOD
#define vI_W25Q_DualBank_BK1IO0_PinNum                             11

#define pI_W25Q_DualBank_BK1IO1_GPIOx                              GPIOD
#define vI_W25Q_DualBank_BK1IO1_PinNum                             12

#define pI_W25Q_DualBank_BK1IO2_GPIOx                              GPIOE
#define vI_W25Q_DualBank_BK1IO2_PinNum                             2

#define pI_W25Q_DualBank_BK1IO3_GPIOx                              GPIOD
#define vI_W25Q_DualBank_BK1IO3_PinNum                             13


//Bank2

//#define pI_W25Q_DualBank_BK2CS_GPIOx
//#define vI_W25Q_DualBank_BK2CS_PinNum

#define pI_W25Q_DualBank_BK2IO0_GPIOx                              GPIOE
#define vI_W25Q_DualBank_BK2IO0_PinNum                             7

#define pI_W25Q_DualBank_BK2IO1_GPIOx                              GPIOE
#define vI_W25Q_DualBank_BK2IO1_PinNum                             8

#define pI_W25Q_DualBank_BK2IO2_GPIOx                              GPIOE
#define vI_W25Q_DualBank_BK2IO2_PinNum                             9

#define pI_W25Q_DualBank_BK2IO3_GPIOx                              GPIOE
#define vI_W25Q_DualBank_BK2IO3_PinNum                             10




//设置输入输出
#define oI_W25Q_DualBank_BK1IO0_Mode_Input()    pI_W25Q_DualBank_BK1IO0_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK1IO0_PinNum*2)))
#define oI_W25Q_DualBank_BK1IO0_Mode_Output()     pI_W25Q_DualBank_BK1IO0_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK1IO0_PinNum*2))

#define oI_W25Q_DualBank_BK1IO1_Mode_Input()    pI_W25Q_DualBank_BK1IO1_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK1IO1_PinNum*2)))
#define oI_W25Q_DualBank_BK1IO1_Mode_Output()     pI_W25Q_DualBank_BK1IO1_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK1IO1_PinNum*2))

#define oI_W25Q_DualBank_BK1IO2_Mode_Input()    pI_W25Q_DualBank_BK1IO2_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK1IO2_PinNum*2)))
#define oI_W25Q_DualBank_BK1IO2_Mode_Output()     pI_W25Q_DualBank_BK1IO2_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK1IO2_PinNum*2))

#define oI_W25Q_DualBank_BK1IO3_Mode_Input()    pI_W25Q_DualBank_BK1IO3_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK1IO3_PinNum*2)))
#define oI_W25Q_DualBank_BK1IO3_Mode_Output()     pI_W25Q_DualBank_BK1IO3_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK1IO3_PinNum*2))

#define oI_W25Q_DualBank_BK2IO0_Mode_Input()    pI_W25Q_DualBank_BK2IO0_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK2IO0_PinNum*2)))
#define oI_W25Q_DualBank_BK2IO0_Mode_Output()     pI_W25Q_DualBank_BK2IO0_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK2IO0_PinNum*2))

#define oI_W25Q_DualBank_BK2IO1_Mode_Input()    pI_W25Q_DualBank_BK2IO1_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK2IO1_PinNum*2)))
#define oI_W25Q_DualBank_BK2IO1_Mode_Output()     pI_W25Q_DualBank_BK2IO1_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK2IO1_PinNum*2))

#define oI_W25Q_DualBank_BK2IO2_Mode_Input()    pI_W25Q_DualBank_BK2IO2_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK2IO2_PinNum*2)))
#define oI_W25Q_DualBank_BK2IO2_Mode_Output()     pI_W25Q_DualBank_BK2IO2_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK2IO2_PinNum*2))

#define oI_W25Q_DualBank_BK2IO3_Mode_Input()    pI_W25Q_DualBank_BK2IO3_GPIOx->MODER&=(~(0x3U<<(vI_W25Q_DualBank_BK2IO3_PinNum*2)))
#define oI_W25Q_DualBank_BK2IO3_Mode_Output()     pI_W25Q_DualBank_BK2IO3_GPIOx->MODER|=(0x1U<<(vI_W25Q_DualBank_BK2IO3_PinNum*2))


//置位 复位

#define oI_W25Q_DualBank_SCK_SetOutput_High()    oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_SCK_GPIOx,vI_W25Q_DualBank_SCK_PinNum)
#define oI_W25Q_DualBank_SCK_SetOutput_Low()     oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_SCK_GPIOx,vI_W25Q_DualBank_SCK_PinNum)


#if defined(pI_W25Q_DualBank_BK1CS_GPIOx)&&defined(vI_W25Q_DualBank_BK1CS_PinNum)
#define oI_W25Q_DualBank_BK1CS_SetOutput_High()  oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK1CS_GPIOx,vI_W25Q_DualBank_BK1CS_PinNum)
#define oI_W25Q_DualBank_BK1CS_SetOutput_Low()   oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK1CS_GPIOx,vI_W25Q_DualBank_BK1CS_PinNum)
#endif

#define oI_W25Q_DualBank_BK1IO0_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK1IO0_GPIOx,vI_W25Q_DualBank_BK1IO0_PinNum)
#define oI_W25Q_DualBank_BK1IO0_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK1IO0_GPIOx,vI_W25Q_DualBank_BK1IO0_PinNum)

#define oI_W25Q_DualBank_BK1IO1_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK1IO1_GPIOx,vI_W25Q_DualBank_BK1IO1_PinNum)
#define oI_W25Q_DualBank_BK1IO1_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK1IO1_GPIOx,vI_W25Q_DualBank_BK1IO1_PinNum)

#define oI_W25Q_DualBank_BK1IO2_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK1IO2_GPIOx,vI_W25Q_DualBank_BK1IO2_PinNum)
#define oI_W25Q_DualBank_BK1IO2_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK1IO2_GPIOx,vI_W25Q_DualBank_BK1IO2_PinNum)

#define oI_W25Q_DualBank_BK1IO3_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK1IO3_GPIOx,vI_W25Q_DualBank_BK1IO3_PinNum)
#define oI_W25Q_DualBank_BK1IO3_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK1IO3_GPIOx,vI_W25Q_DualBank_BK1IO3_PinNum)


#if defined(pI_W25Q_DualBank_BK2CS_GPIOx)&&defined(vI_W25Q_DualBank_BK2CS_PinNum)
#define oI_W25Q_DualBank_BK2CS_SetOutput_High()  oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK2CS_GPIOx,vI_W25Q_DualBank_BK2CS_PinNum)
#define oI_W25Q_DualBank_BK2CS_SetOutput_Low()   oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK2CS_GPIOx,vI_W25Q_DualBank_BK2CS_PinNum)
#endif

#define oI_W25Q_DualBank_BK2IO0_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK2IO0_GPIOx,vI_W25Q_DualBank_BK2IO0_PinNum)
#define oI_W25Q_DualBank_BK2IO0_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK2IO0_GPIOx,vI_W25Q_DualBank_BK2IO0_PinNum)

#define oI_W25Q_DualBank_BK2IO1_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK2IO1_GPIOx,vI_W25Q_DualBank_BK2IO1_PinNum)
#define oI_W25Q_DualBank_BK2IO1_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK2IO1_GPIOx,vI_W25Q_DualBank_BK2IO1_PinNum)

#define oI_W25Q_DualBank_BK2IO2_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK2IO2_GPIOx,vI_W25Q_DualBank_BK2IO2_PinNum)
#define oI_W25Q_DualBank_BK2IO2_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK2IO2_GPIOx,vI_W25Q_DualBank_BK2IO2_PinNum)

#define oI_W25Q_DualBank_BK2IO3_SetOutput_High() oIP_GPIO_SetOutput_High(pI_W25Q_DualBank_BK2IO3_GPIOx,vI_W25Q_DualBank_BK2IO3_PinNum)
#define oI_W25Q_DualBank_BK2IO3_SetOutput_Low()  oIP_GPIO_SetOutput_Low( pI_W25Q_DualBank_BK2IO3_GPIOx,vI_W25Q_DualBank_BK2IO3_PinNum)


#define oI_W25Q_DualBank_BKIO_SetOutput_High()  oI_W25Q_DualBank_BK1IO0_SetOutput_High();\
                                                oI_W25Q_DualBank_BK1IO1_SetOutput_High();\
                                                oI_W25Q_DualBank_BK1IO2_SetOutput_High();\
                                                oI_W25Q_DualBank_BK1IO3_SetOutput_High();\
                                                oI_W25Q_DualBank_BK2IO0_SetOutput_High();\
                                                oI_W25Q_DualBank_BK2IO1_SetOutput_High();\
                                                oI_W25Q_DualBank_BK2IO2_SetOutput_High();\
                                                oI_W25Q_DualBank_BK2IO3_SetOutput_High()
#define oI_W25Q_DualBank_BKIO_SetOutput_Low() 	oI_W25Q_DualBank_BK1IO0_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK1IO1_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK1IO2_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK1IO3_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK2IO0_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK2IO1_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK2IO2_SetOutput_Low();\
                                                oI_W25Q_DualBank_BK2IO3_SetOutput_Low()

#if defined(pI_W25Q_DualBank_BK1CS_GPIOx)&&defined(vI_W25Q_DualBank_BK1CS_PinNum)&&defined(pI_W25Q_DualBank_BK2CS_GPIOx)&&defined(vI_W25Q_DualBank_BK2CS_PinNum)

#define oI_W25Q_DualBank_BKCS_SetOutput_High()    oI_W25Q_DualBank_BK1CS_SetOutput_High();oI_W25Q_DualBank_BK2CS_SetOutput_High()
#define oI_W25Q_DualBank_BKCS_SetOutput_Low()     oI_W25Q_DualBank_BK1CS_SetOutput_Low();_I_W25Q_DualBank_BK2CS_SetOutput_Low()

#else 

#if defined(pI_W25Q_DualBank_BK1CS_GPIOx)&&defined(vI_W25Q_DualBank_BK1CS_PinNum)

#define oI_W25Q_DualBank_BKCS_SetOutput_High()    oI_W25Q_DualBank_BK1CS_SetOutput_High()
#define oI_W25Q_DualBank_BKCS_SetOutput_Low()     oI_W25Q_DualBank_BK1CS_SetOutput_Low()

#elif defined(pI_W25Q_DualBank_BK2CS_GPIOx)&&defined(vI_W25Q_DualBank_BK2CS_PinNum)

#define oI_W25Q_DualBank_BKCS_SetOutput_High() 		oI_W25Q_DualBank_BK2CS_SetOutput_High()
#define oI_W25Q_DualBank_BKCS_SetOutput_Low() 	  oI_W25Q_DualBank_BK2CS_SetOutput_Low()

#endif

#endif


#define oI_W25Q_DualBank_BKIO_OUT()   oI_W25Q_DualBank_BK1IO0_Mode_Output();\
                                      oI_W25Q_DualBank_BK1IO1_Mode_Output();\
                                      oI_W25Q_DualBank_BK1IO2_Mode_Output();\
                                      oI_W25Q_DualBank_BK1IO3_Mode_Output();\
                                      oI_W25Q_DualBank_BK2IO0_Mode_Output();\
                                      oI_W25Q_DualBank_BK2IO1_Mode_Output();\
                                      oI_W25Q_DualBank_BK2IO2_Mode_Output();\
                                      oI_W25Q_DualBank_BK2IO3_Mode_Output()
#define oI_W25Q_DualBank_BKIO_IN()    oI_W25Q_DualBank_BK1IO0_Mode_Input();\
                                      oI_W25Q_DualBank_BK1IO1_Mode_Input();\
                                      oI_W25Q_DualBank_BK1IO2_Mode_Input();\
                                      oI_W25Q_DualBank_BK1IO3_Mode_Input();\
                                      oI_W25Q_DualBank_BK2IO0_Mode_Input();\
                                      oI_W25Q_DualBank_BK2IO1_Mode_Input();\
                                      oI_W25Q_DualBank_BK2IO2_Mode_Input();\
                                      oI_W25Q_DualBank_BK2IO3_Mode_Input()



//读取输入

#define oI_W25Q_DualBank_BK1IO0_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK1IO0_GPIOx,vI_W25Q_DualBank_BK1IO0_PinNum)
#define oI_W25Q_DualBank_BK1IO1_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK1IO1_GPIOx,vI_W25Q_DualBank_BK1IO1_PinNum)
#define oI_W25Q_DualBank_BK1IO2_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK1IO2_GPIOx,vI_W25Q_DualBank_BK1IO2_PinNum)
#define oI_W25Q_DualBank_BK1IO3_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK1IO3_GPIOx,vI_W25Q_DualBank_BK1IO3_PinNum)

#define oI_W25Q_DualBank_BK2IO0_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK2IO0_GPIOx,vI_W25Q_DualBank_BK2IO0_PinNum)
#define oI_W25Q_DualBank_BK2IO1_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK2IO1_GPIOx,vI_W25Q_DualBank_BK2IO1_PinNum)
#define oI_W25Q_DualBank_BK2IO2_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK2IO2_GPIOx,vI_W25Q_DualBank_BK2IO2_PinNum)
#define oI_W25Q_DualBank_BK2IO3_GetInputBit()    oIP_GPIO_GetInputBit(pI_W25Q_DualBank_BK2IO3_GPIOx,vI_W25Q_DualBank_BK2IO3_PinNum)






static void SetIO_1Line(void);

static void IO_Init(){

  
	RCC->AHB4ENR|=RCC_AHB4ENR_GPIOBEN|RCC_AHB4ENR_GPIODEN|RCC_AHB4ENR_GPIOEEN|RCC_AHB4ENR_GPIOGEN|RCC_AHB4ENR_GPIOHEN;


  oI_W25Q_DualBank_SCK_SetOutput_Low();
  oI_W25Q_DualBank_BKCS_SetOutput_High();

  oIP_GPIO_Config(pI_W25Q_DualBank_SCK_GPIOx,vI_W25Q_DualBank_SCK_PinNum,vIP_GPIO_Mode_OUT,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);

  oIP_GPIO_Config(pI_W25Q_DualBank_BK1CS_GPIOx,vI_W25Q_DualBank_BK1CS_PinNum,vIP_GPIO_Mode_OUT,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK1IO0_GPIOx,vI_W25Q_DualBank_BK1IO0_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK1IO1_GPIOx,vI_W25Q_DualBank_BK1IO1_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK1IO2_GPIOx,vI_W25Q_DualBank_BK1IO2_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK1IO3_GPIOx,vI_W25Q_DualBank_BK1IO3_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);

	//oIP_GPIO_Config(pI_W25Q_DualBank_BK1CS_GPIOx,vI_W25Q_DualBank_BK2CS_PinNum,vIP_GPIO_Mode_OUT,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK2IO0_GPIOx,vI_W25Q_DualBank_BK2IO0_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK2IO1_GPIOx,vI_W25Q_DualBank_BK2IO1_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK2IO2_GPIOx,vI_W25Q_DualBank_BK2IO2_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(pI_W25Q_DualBank_BK2IO3_GPIOx,vI_W25Q_DualBank_BK2IO3_PinNum,vIP_GPIO_Mode_IN,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_MEDIUM,vIP_GPIO_PuPd_NP);


  SetIO_1Line();
}

//延时50ns以上的时间 以保证CS的高电平时间
static void Delay50ns(){

  __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
  __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
}

static void SetIO_1Line(){

  oI_W25Q_DualBank_BK1IO2_SetOutput_High();
  oI_W25Q_DualBank_BK2IO2_SetOutput_High();
  oI_W25Q_DualBank_BK1IO3_SetOutput_High();
  oI_W25Q_DualBank_BK2IO3_SetOutput_High();

  oI_W25Q_DualBank_BK1IO0_Mode_Output();
  oI_W25Q_DualBank_BK1IO1_Mode_Input();
  oI_W25Q_DualBank_BK1IO2_Mode_Output();
  oI_W25Q_DualBank_BK1IO3_Mode_Output();

  oI_W25Q_DualBank_BK2IO0_Mode_Output();
  oI_W25Q_DualBank_BK2IO1_Mode_Input();
  oI_W25Q_DualBank_BK2IO2_Mode_Output();
  oI_W25Q_DualBank_BK2IO3_Mode_Output();
}

//单线传输数据
static unsigned short TxRxByte(unsigned short txdata){
  unsigned int tx1,tx2,rx1,rx2;
  unsigned int Mask;


  tx1=0x000000FFU&txdata;
  tx2=0x000000FFU&(txdata>>8);


  Mask=0x80U;
  rx1=0U;
  rx2=0U;
  while(Mask){
    
    if(Mask&tx1){
      oI_W25Q_DualBank_BK1IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO0_SetOutput_Low();
    }

    if(Mask&tx2){
      oI_W25Q_DualBank_BK2IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO0_SetOutput_Low();
    }

    oI_W25Q_DualBank_SCK_SetOutput_High();
    
    rx1<<=1;
    rx2<<=1;
    if(oI_W25Q_DualBank_BK1IO1_GetInputBit()){
      rx1|=0x01U;
    }
    else{
      rx1&=0xFEU;
    }
    if(oI_W25Q_DualBank_BK2IO1_GetInputBit()){
      rx2|=0x01U;
    }
    else{
      rx2&=0xFEU;
    }

    Mask>>=1;
    oI_W25Q_DualBank_SCK_SetOutput_Low();

  }

  return rx1|(rx2<<8);
}

//四线发送字节
void Tx_4Line(unsigned char *src,unsigned int Len){
  unsigned char Temp1,Temp2;

  if(0x00000001U&Len){//保证Len为2的倍数
    Len+=1U;
  }

  Temp1=*src;
  src++;
  Temp2=*src;
  src++;

  while(Len){
    Len-=2;

    //发送一个字节

    if(0x80U&Temp1){
      oI_W25Q_DualBank_BK1IO3_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO3_SetOutput_Low();
    }
    if(0x40U&Temp1){
      oI_W25Q_DualBank_BK1IO2_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO2_SetOutput_Low();
    }
    if(0x20U&Temp1){
      oI_W25Q_DualBank_BK1IO1_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO1_SetOutput_Low();
    }
    if(0x10U&Temp1){
      oI_W25Q_DualBank_BK1IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO0_SetOutput_Low();
    }

    if(0x80U&Temp2){
      oI_W25Q_DualBank_BK2IO3_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO3_SetOutput_Low();
    }
    if(0x40U&Temp2){
      oI_W25Q_DualBank_BK2IO2_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO2_SetOutput_Low();
    }
    if(0x20U&Temp2){
      oI_W25Q_DualBank_BK2IO1_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO1_SetOutput_Low();
    }
    if(0x10U&Temp2){
      oI_W25Q_DualBank_BK2IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO0_SetOutput_Low();
    }

    oI_W25Q_DualBank_SCK_SetOutput_High();
    Temp1<<=4;
    Temp2<<=4;
    oI_W25Q_DualBank_SCK_SetOutput_Low();

    //发送一个字节
    if(0x80U&Temp1){
      oI_W25Q_DualBank_BK1IO3_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO3_SetOutput_Low();
    }
    if(0x40U&Temp1){
      oI_W25Q_DualBank_BK1IO2_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO2_SetOutput_Low();
    }
    if(0x20U&Temp1){
      oI_W25Q_DualBank_BK1IO1_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO1_SetOutput_Low();
    }
    if(0x10U&Temp1){
      oI_W25Q_DualBank_BK1IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK1IO0_SetOutput_Low();
    }

    if(0x80U&Temp2){
      oI_W25Q_DualBank_BK2IO3_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO3_SetOutput_Low();
    }
    if(0x40U&Temp2){
      oI_W25Q_DualBank_BK2IO2_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO2_SetOutput_Low();
    }
    if(0x20U&Temp2){
      oI_W25Q_DualBank_BK2IO1_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO1_SetOutput_Low();
    }
    if(0x10U&Temp2){
      oI_W25Q_DualBank_BK2IO0_SetOutput_High();
    }
    else{
      oI_W25Q_DualBank_BK2IO0_SetOutput_Low();
    }

    //更换到下一组数据
    oI_W25Q_DualBank_SCK_SetOutput_High();
    Temp1=*src;
    src++;
    Temp2=*src;
    src++;
    oI_W25Q_DualBank_SCK_SetOutput_Low();
  }

}

//四线接收字节
void Rx_4Line(unsigned char *dst,unsigned int Len){
  unsigned char Temp1,Temp2;

  if(0x00000001U&Len){//保证Len为2的倍数
    Len+=1U;
  }


  while(Len){
    Len-=2U;

    Temp1=0;
    Temp2=0;

    oI_W25Q_DualBank_SCK_SetOutput_High();

    if(oI_W25Q_DualBank_BK1IO3_GetInputBit()){
      Temp1|=0x08U;
    }
    else{
      Temp1&=0xF7U;
    }
    if(oI_W25Q_DualBank_BK1IO2_GetInputBit()){
      Temp1|=0x04U;
    }
    else{
      Temp1&=0xFBU;
    }
    if(oI_W25Q_DualBank_BK1IO1_GetInputBit()){
      Temp1|=0x02U;
    }
    else{
      Temp1&=0xFDU;
    }
    if(oI_W25Q_DualBank_BK1IO0_GetInputBit()){
      Temp1|=0x01U;
    }
    else{
      Temp1&=0xFEU;
    }

    if(oI_W25Q_DualBank_BK2IO3_GetInputBit()){
      Temp2|=0x08U;
    }
    else{
      Temp2&=0xF7U;
    }
    if(oI_W25Q_DualBank_BK2IO2_GetInputBit()){
      Temp2|=0x04U;
    }
    else{
      Temp2&=0xFBU;
    }
    if(oI_W25Q_DualBank_BK2IO1_GetInputBit()){
      Temp2|=0x02U;
    }
    else{
      Temp2&=0xFDU;
    }
    if(oI_W25Q_DualBank_BK2IO0_GetInputBit()){
      Temp2|=0x01U;
    }
    else{
      Temp2&=0xFEU;
    }

    oI_W25Q_DualBank_SCK_SetOutput_Low();
    Temp1<<=4;
    Temp2<<=4;
    oI_W25Q_DualBank_SCK_SetOutput_High();

    if(oI_W25Q_DualBank_BK1IO3_GetInputBit()){
      Temp1|=0x08U;
    }
    else{
      Temp1&=0xF7U;
    }
    if(oI_W25Q_DualBank_BK1IO2_GetInputBit()){
      Temp1|=0x04U;
    }
    else{
      Temp1&=0xFBU;
    }
    if(oI_W25Q_DualBank_BK1IO1_GetInputBit()){
      Temp1|=0x02U;
    }
    else{
      Temp1&=0xFDU;
    }
    if(oI_W25Q_DualBank_BK1IO0_GetInputBit()){
      Temp1|=0x01U;
    }
    else{
      Temp1&=0xFEU;
    }

    if(oI_W25Q_DualBank_BK2IO3_GetInputBit()){
      Temp2|=0x08U;
    }
    else{
      Temp2&=0xF7U;
    }
    if(oI_W25Q_DualBank_BK2IO2_GetInputBit()){
      Temp2|=0x04U;
    }
    else{
      Temp2&=0xFBU;
    }
    if(oI_W25Q_DualBank_BK2IO1_GetInputBit()){
      Temp2|=0x02U;
    }
    else{
      Temp2&=0xFDU;
    }
    if(oI_W25Q_DualBank_BK2IO0_GetInputBit()){
      Temp2|=0x01U;
    }
    else{
      Temp2&=0xFEU;
    }

    oI_W25Q_DualBank_SCK_SetOutput_Low();

    *dst=Temp1;
    dst++;
    *dst=Temp2;
    dst++;
  }

}






//=======================================================================================================
//
//
//          w25q部分
//
//
//=======================================================================================================

#define cI_W25Q_CMD_8to16(cmd) ((unsigned short)(cmd)|((((unsigned short)(cmd))<<8)&0xFF00U))

//初始化W25Q_DualBank的IO
void I_W25Q_DualBank_Init(){

  IO_Init();
}

//获取ID
unsigned int I_W25Q_DualBank_GetID(){
  unsigned int W25Q16_ID;
  unsigned short t;

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_GetID));
  TxRxByte(0x0000U);
  TxRxByte(0x0000U);
  TxRxByte(0x0000U);
  t=TxRxByte(0xFFFFU);
  W25Q16_ID=(0xFF000000U&(t<<16))|(0x0000FF00U&(t<<8));
  t=TxRxByte(0xFFFFU);
  W25Q16_ID|=(0x00FF0000U&(t<<8))|(0x000000FFU&t);
  oI_W25Q_DualBank_BKCS_SetOutput_High();

  return W25Q16_ID;
}

//读取状态寄存器1
unsigned short I_W25Q_DualBank_GetStatusReg1(){
  volatile unsigned short readData=0U;

  oI_W25Q_DualBank_BKCS_SetOutput_Low();

  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_ReadREG_Status1));
  readData=TxRxByte(0xFFFFU);

  oI_W25Q_DualBank_BKCS_SetOutput_High();

  return (unsigned short)readData;
}

//读取状态寄存器2
unsigned short I_W25Q_DualBank_GetStatusReg2(){
  volatile unsigned short readData=0U;

  oI_W25Q_DualBank_BKCS_SetOutput_Low();

  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_ReadREG_Status2));
  readData=TxRxByte(0xFFFFU);

  oI_W25Q_DualBank_BKCS_SetOutput_High();

  return (unsigned short)readData;
}

//读取状态寄存器3
unsigned short I_W25Q_DualBank_GetStatusReg3(){
  volatile unsigned short readData=0U;

  oI_W25Q_DualBank_BKCS_SetOutput_Low();

  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_ReadREG_Status3));
  readData=TxRxByte(0xFFFFU);

  oI_W25Q_DualBank_BKCS_SetOutput_High();

  return (unsigned short)readData;
}

void I_W25Q_DualBank_WaitBusy(){

  while((cI_W25Q_CMD_8to16(vI_W25Q_Status_BUSY)&I_W25Q_DualBank_GetStatusReg1())!=0){
    //等待BUSY为0
  }
}

//获取容量
void I_W25Q_DualBank_GetSize(unsigned int *Size1,unsigned int *Size2){

  unsigned int id;
  unsigned short id1,id2;

  I_W25Q_DualBank_WaitBusy();
  id=I_W25Q_DualBank_GetID();
  id1=(unsigned short)(0x0000FFFFU&id);
  id2=(unsigned short)(0x0000FFFFU&(id>>16));

  if(id1==vI_W25Q_ID_80){
    *Size1=1024U*1024U;
  }else if(id1==vI_W25Q_ID_16){
    *Size1= 2U*1024U*1024U;
  }else if(id1==vI_W25Q_ID_32){
    *Size1= 4U*1024U*1024U;
  }else if(id1==vI_W25Q_ID_64){
    *Size1= 8U*1024U*1024U;
  }else if(id1==vI_W25Q_ID_128){
    *Size1= 16U*1024U*1024U;
  }else{
    *Size1= 0U;
  }

  if(id2==vI_W25Q_ID_80){
    *Size2= 1024U*1024U;
  }else if(id2==vI_W25Q_ID_16){
    *Size2= 2U*1024U*1024U;
  }else if(id2==vI_W25Q_ID_32){
    *Size2= 4U*1024U*1024U;
  }else if(id2==vI_W25Q_ID_64){
    *Size2= 8U*1024U*1024U;
  }else if(id2==vI_W25Q_ID_128){
    *Size2= 16U*1024U*1024U;
  }else{
    *Size2= 0U;
  }
}



//写状态寄存器
void I_W25Q_DualBank_SetStatusReg1(unsigned short value){

  I_W25Q_DualBank_WaitBusy();
  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_WriteREG_Status1));
  TxRxByte(value);
  oI_W25Q_DualBank_BKCS_SetOutput_High();
}
//写状态寄存器
void I_W25Q_DualBank_SetStatusReg2(unsigned short value){

  I_W25Q_DualBank_WaitBusy();
  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_WriteREG_Status2));
  TxRxByte(value);
  oI_W25Q_DualBank_BKCS_SetOutput_High();
}
//写状态寄存器
void I_W25Q_DualBank_SetStatusReg3(unsigned short value){

  I_W25Q_DualBank_WaitBusy();
  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_WriteREG_Status3));
  TxRxByte(value);
  oI_W25Q_DualBank_BKCS_SetOutput_High();
}

//状态寄存器写使能
void I_W25Q_DualBank_RegWriteEnable(){

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_StatusREGWriteEnable));
  oI_W25Q_DualBank_BKCS_SetOutput_High();
}

//写使能
void I_W25Q_DualBank_WriteEnable(){

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_WriteEnable));
  oI_W25Q_DualBank_BKCS_SetOutput_High();
}

//设置为quad模式
void I_W25Q_DualBank_SetQuad(){

  if((cI_W25Q_CMD_8to16(vI_W25Q_Status_QE)&I_W25Q_DualBank_GetStatusReg2())!=cI_W25Q_CMD_8to16(vI_W25Q_Status_QE)){//有不为qe模式
    I_W25Q_DualBank_WriteEnable();
    I_W25Q_DualBank_SetStatusReg2(cI_W25Q_CMD_8to16(vI_W25Q_Status_QE));
  }

  if(((cI_W25Q_CMD_8to16(vI_W25Q_Status_DRV1|vI_W25Q_Status_DRV2))&I_W25Q_DualBank_GetStatusReg3())!=0){//W25Q_Status_DRV1|W25Q_Status_DRV2不为0
    I_W25Q_DualBank_WriteEnable();
    I_W25Q_DualBank_SetStatusReg3(0U);
  }
}


//=======================================================================================================
//读写操作
//=======================================================================================================


//读数据 FastRead
void I_W25Q_DualBank_ReadData(unsigned int W25qADDR,unsigned char *dst,int Len){
  volatile unsigned char temp[8];

  
  W25qADDR>>=1;//flash地址

  temp[0]=(unsigned char)((W25qADDR>>16)&0x000000FFU);
  temp[2]=(unsigned char)((W25qADDR>>8)&0x000000FFU);
  temp[4]=(unsigned char)(W25qADDR&0x000000FFU);
  temp[6]=0xFFU;

  temp[1]=temp[0];
  temp[3]=temp[2];
  temp[5]=temp[4];
  temp[7]=0xFFU;


  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_FastReadQuad_IO));
  oI_W25Q_DualBank_BKIO_OUT();
  Tx_4Line((unsigned char *)temp,8);
  oI_W25Q_DualBank_BKIO_IN();
  Rx_4Line((unsigned char *)temp,4);
  Rx_4Line(dst,Len);

  oI_W25Q_DualBank_BKCS_SetOutput_High();
  SetIO_1Line();
}

//读数据 可以不2字节对齐
void I_W25Q_DualBank_ReadData_noAlign(unsigned int W25qADDR,unsigned char *dst,int Len){
	unsigned char tData[2];
	
	if(W25qADDR&0x00000001U){
		W25qADDR-=1;
		I_W25Q_DualBank_ReadData(W25qADDR,tData,2);
		*dst=tData[1];
		dst++;
		W25qADDR+=2U;
		I_W25Q_DualBank_ReadData(W25qADDR,dst,Len-1);
	}else{
		I_W25Q_DualBank_ReadData(W25qADDR,dst,Len);
	}
}


//写数据
void I_W25Q_DualBank_PageProgram(unsigned int W25qADDR,unsigned char *src,int Len){

  W25qADDR>>=1;

  I_W25Q_DualBank_WaitBusy();//wait...
  I_W25Q_DualBank_WriteEnable();
  I_W25Q_DualBank_WaitBusy();//wait...

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_QuadPageProgram));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>16)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>8)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)W25qADDR));
  oI_W25Q_DualBank_BKIO_OUT();
  Tx_4Line(src,Len);

  Delay50ns();
  oI_W25Q_DualBank_BKCS_SetOutput_High();
  
  SetIO_1Line();
}


//擦除 8192字节
void I_W25Q_DualBank_Erase(unsigned int W25qADDR){

  W25qADDR>>=1;
  W25qADDR&=0xFFFFF000U;

  I_W25Q_DualBank_WaitBusy();//wait...
  I_W25Q_DualBank_WriteEnable();
  I_W25Q_DualBank_WaitBusy();//wait...

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_SectorErase));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>16)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>8)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)W25qADDR));
  
  Delay50ns();
  oI_W25Q_DualBank_BKCS_SetOutput_High();

}

//擦除 64*1024字节
void I_W25Q_DualBank_64KBErase(unsigned int W25qADDR){

  W25qADDR>>=1;
  W25qADDR&=0xFFFFF000U;

  I_W25Q_DualBank_WaitBusy();//wait...
  I_W25Q_DualBank_WriteEnable();
  I_W25Q_DualBank_WaitBusy();//wait...

  oI_W25Q_DualBank_BKCS_SetOutput_Low();
  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_32KBErase));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>16)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>8)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)W25qADDR));
  
  Delay50ns();
  oI_W25Q_DualBank_BKCS_SetOutput_High();

}

//擦除 128*1024字节
void I_W25Q_DualBank_128KBErase(unsigned int W25qADDR){

  W25qADDR>>=1;
  W25qADDR&=0xFFFFF000U;

  I_W25Q_DualBank_WaitBusy();//wait...
  I_W25Q_DualBank_WriteEnable();
  I_W25Q_DualBank_WaitBusy();//wait...

  oI_W25Q_DualBank_BKCS_SetOutput_Low();

  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_64KBErase));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>16)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)(W25qADDR>>8)));
  TxRxByte(cI_W25Q_CMD_8to16((unsigned char)W25qADDR));

  Delay50ns();
  oI_W25Q_DualBank_BKCS_SetOutput_High();

}

//全片擦除
void I_W25Q_DualBank_ChipErase(){

  I_W25Q_DualBank_WaitBusy();//wait...
  I_W25Q_DualBank_WriteEnable();
  I_W25Q_DualBank_WaitBusy();//wait...

  oI_W25Q_DualBank_BKCS_SetOutput_Low();

  TxRxByte(cI_W25Q_CMD_8to16(vI_W25Q_CMD_ChipErase));

  Delay50ns();
  oI_W25Q_DualBank_BKCS_SetOutput_High();

  I_W25Q_DualBank_WaitBusy();//wait...
}



